﻿using System;
using System.Linq.Expressions;
using System.Collections.Generic;

namespace EmbeddedLanguage.SubProcessors
{
    public class Method2StaticFunctionMappingProcessor : ExpressionVisitor
    {
        [ThreadStatic]
        public static Dictionary<Tuple<Type, string>, string> MethodSubstitions = new Dictionary<Tuple<Type, string>, string>();


        protected override Expression VisitLambda<T>(Expression<T> node)
        {
            this.Visit(node.Body);
            return node;
        }

        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (node.Arguments.Count == 3)
            {
                if (node.Method.Name.StartsWith("AssignStatic"))
                {
                    var compiledExpr = node.Arguments[1];
                    var compiledMember = compiledExpr as MemberExpression;
                    var localMethodType = compiledMember.Member.ReflectedType;
                    string methodName = compiledMember.Member.Name;
                    
                    var expr = node.Arguments[2];
                    var exprMember = expr as LambdaExpression;
                    var lambdaBody = exprMember.Body as InvocationExpression;
                    var args_0 = lambdaBody.Arguments[0];
                    string staticFunctionType = ExpressionToJSProcessor.GetFullName(args_0.Type);
                    var invokeExpress = lambdaBody.Expression;
                    var memberE = invokeExpress as MemberExpression;
                    string staticFunctionName = memberE.Member.Name;
                    //string staticFunctionType = ExpressionToJSProcessor.GetFullName( exprMember.Member.ReflectedType);
                    //string staticFunctionName = exprMember.Member.Name;
                    var tupleKey = new Tuple<Type, string>(localMethodType, methodName);
                    MethodSubstitions[tupleKey] = staticFunctionType + "." + staticFunctionName;
                    
                }
                
            }
            return base.VisitMethodCall(node);
            //return node;
        }
    }
}
